package com.phison.fenestrapro.dashboard.widgetset.client;

import java.util.Date;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window.Location;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.PopupPanel;
import com.vaadin.terminal.gwt.client.ui.VNotification;

/**
 * TODO better default styles via css
 * 
 */
public class DefaultTimeoutWarningImpl extends VNotification implements
		TimeoutWarning {

	private long timeoutTs;
	private HTML clock;

	@SuppressWarnings("deprecation")
	public DefaultTimeoutWarningImpl() {
		super(DELAY_FOREVER, 500, 65);
		setPosition(TOP_RIGHT);
		Style style = getElement().getStyle();
		style.setBackgroundColor("gray");
		addStyleName("smart-session-warning");
	}

	private RepeatingCommand clockTimer = new RepeatingCommand() {
		public boolean execute() {
			if (!isShowing()) {
				return false;
			}
			if (applicationConnection.readCookie()) {
				applicationConnection.scheduleSessionWarning();
				return false;
			}

			Date date = new Date();
			boolean expired = date.getTime() > timeoutTs;
			if (!expired) {
				int remaining = (int) ((timeoutTs - date.getTime()) / 1000);
				String msg = "Your session will expire in " + remaining + " seconds";
				clock.setText(msg);
			} else {
				setWidget(new HTML("Your session has expired"));
				applicationConnection.forceExpire();
				setAutoHideEnabled(false);
				show();
				if (applicationConnection.getSessionExpiredUrl() != null) {
					Timer timer = new Timer() {

						@Override
						public void run() {
							Location.assign(applicationConnection
									.getSessionExpiredUrl());

						}
					};
					timer.schedule(2000);
				} else {
					addCloseHandler(new CloseHandler<PopupPanel>() {
						public void onClose(CloseEvent<PopupPanel> event) {
							Location.reload();
						}
					});
				}
				if (applicationConnection.clearScreenOnTimemout()) {
					applicationConnection.getView().removeFromParent();
				}
			}
			return !expired;
		}
	};
	private ApplicationConnection applicationConnection;

	public void show(long timeoutTimeStamp) {
		this.timeoutTs = timeoutTimeStamp;
		
		FlowPanel fp = new FlowPanel();

		Scheduler.get().scheduleFixedPeriod(clockTimer, 1000);
		
		clock = new HTML();
		
		Date date = new Date();
		int remaining = (int) ((timeoutTs - date.getTime()) / 1000);
		String msg = "Your session will expire in " + remaining + " seconds";
		clock.setText(msg);
		
		fp.add(clock);
		
		HTML html = new HTML("<br/><div align='center'>Click here to continue your session</div>");
		fp.add(html);

		setWidget(fp);
		super.show();
	}

	public void setApplicationConnection(
			ApplicationConnection applicationConnection) {
		this.applicationConnection = applicationConnection;
	}

	public void close() {
		hide();
	}

}
